import { initShaders } from '@/lib/webgl'

export default class Ani {
    constructor (el, vertexDatas, vertexCount, xformMatrix, updateCallback) {
        const styles = window.getComputedStyle(el, null)
        el.width = parseInt(styles.width)
        el.height = parseInt(styles.height)
        const gl = el.getContext('webgl2')
        this.gl = gl
        this.xformMatrix = xformMatrix
        this.vertexDatas = vertexDatas
        this.vertexCount = vertexCount
        this.updateCallback = updateCallback
        this.uxformMatrix = null
        this.tick = null

        // 顶点着色器
        const VSHADER_SOURCE = `
            attribute vec4 a_Position;
            uniform mat4 u_xformMatrix;
            void main() {
                gl_Position = u_xformMatrix * a_Position;
                gl_PointSize = 10.0;
            }
        `
        const FSHADER_SOURCE = `
            void main() {
                gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
            }
        `
        if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
            console.log('init shader error')
            return
        }
        // 设置顶点位置
        const n = this.initVertexBuffers(gl)
        if (n < 0) {
            console.log('initVertexBuffers failed')
            return
        }
        gl.clearColor(0.0, 0.0, 0.0, 1.0)
        gl.clear(gl.COLOR_BUFFER_BIT)
        gl.drawArrays(gl.TRIANGLES, 0, n)
    }

    start () {
        this.stop()
        this.update()
    }

    update () {
        const that = this
        if (that.updateCallback) {
            that.updateCallback(that.xformMatrix) // 更新变换矩阵
        }
        const gl = that.gl
        gl.uniformMatrix4fv(that.uxformMatrix, false, that.xformMatrix.elements)
        gl.clear(gl.COLOR_BUFFER_BIT)
        gl.drawArrays(gl.TRIANGLES, 0, that.vertexCount)
        that.tick = requestAnimationFrame(that.update.bind(that))
    }

    stop () {
        if (this.tick) {
            cancelAnimationFrame(this.tick)
        }
    }

    initVertexBuffers () {
        const gl = this.gl
        const uxformMatrix = gl.getUniformLocation(gl.program, 'u_xformMatrix')
        this.uxformMatrix = uxformMatrix
        gl.uniformMatrix4fv(uxformMatrix, false, this.xformMatrix.elements)
        const vertices = new Float32Array(this.vertexDatas)
        const n = this.vertexCount
        // 创建缓冲区
        const buffer = gl.createBuffer()
        if (!buffer) {
            return -1
        }
        // 将缓冲区对象绑定到目标
        gl.bindBuffer(gl.ARRAY_BUFFER, buffer)
        // 向缓冲区对象中写入数据
        gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW)
        const aPosition = gl.getAttribLocation(gl.program, 'a_Position')
        // 将缓冲区对象分配给attribute变量
        gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0)
        // 连接a_Position变量与分配给它的缓冲区对象
        gl.enableVertexAttribArray(aPosition)
        return n
    }
}